package com.alibaba.algo.domain.user;

import cn.hutool.core.map.MapUtil;
import com.alibaba.algo.cooperation.feign.vo.req.CurrentUserReqVO;
import com.alibaba.algo.cooperation.feign.vo.req.GetUserOrgsReqVO;
import com.alibaba.algo.cooperation.feign.vo.req.SelectOrgUserEmployeeVO;
import com.alibaba.algo.cooperation.feign.vo.req.SelectUserListInfoReqVo;
import com.alibaba.algo.cooperation.feign.vo.res.RpcUserInfoVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleListByUserRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectUserListByAppRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectUserListRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.EmployeeInfo;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectUserDetailResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysRoleInfoVO;
import com.alibaba.algo.core.base.*;
import com.alibaba.algo.core.exception.BaseException;
import com.alibaba.algo.dao.user.SysUserMapper;
import com.alibaba.algo.dtos.user.UserOrgInfoResDTO;
import com.alibaba.algo.entity.user.SysRole;
import com.alibaba.algo.entity.user.SysUser;
import com.alibaba.algo.enums.SysUserPassWdSaltEnum;
import com.alibaba.algo.exception.BaseErrorCode;
import com.alibaba.algo.exception.SysUserErrorCode;
import com.xxl.sso.core.login.SsoTokenLoginHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类SysUser.java的实现描述：用户表Domain
 *
 * @author nieganggang 2021-03-12 16:08:17
 */
@Component
@Slf4j
public class SysUserDomain extends BaseDomain<SysUser> {

    @Resource
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleDomain sysRoleDomain;


    public PagerEntity selectPageByApp(SelectUserListByAppRequestVO vo) {
        SelectUserListRequestVO selectUserListRequestVO = new SelectUserListRequestVO();
        BeanUtils.copyProperties(vo,selectUserListRequestVO);

        if (ObjectUtils.isEmpty(vo.getPageIndex())) {
            throw new BaseException(BaseErrorCode.PAGE_INDEX_IS_NULL.getCode(), BaseErrorCode.PAGE_INDEX_IS_NULL.getMessage());
        }
        if (ObjectUtils.isEmpty(vo.getPageSize())) {
            throw new BaseException(BaseErrorCode.PAGE_SIZE_IS_NULL.getCode(), BaseErrorCode.PAGE_SIZE_IS_NULL.getMessage());
        }

        Integer total = sysUserMapper.countByPageByApp(vo);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectUserDetailResponseVO> result = sysUserMapper
                .selectPageByApp(vo, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(vo.getSortMap()));
        // 对角色去重
        Set<Long> roleIdSet = new HashSet<>();
        result.stream().filter(s -> !StringUtils.isEmpty(s.getRoles()))
                .forEach(s -> {
                    String[] roleIds = s.getRoles().trim().split(",");
                    for (String roleId : roleIds) {
                        roleIdSet.add(Long.valueOf(roleId));
                    }
                });
        List<Long> roleIdList = new ArrayList<>(roleIdSet);

        // 角色集合
        Map<Long, SysRole> sysRoleMap = sysRoleDomain.qryRoleMapByIdList(roleIdList);
        result.stream()
                .filter(s -> !StringUtils.isEmpty(s.getRoles()))
                .forEach(s -> {
                    List<String> roleIds = Arrays.asList(s.getRoles().trim().split(","));
                    roleIds.forEach(roleId -> {
                        SysRoleInfoVO sysRoleInfoVO = this.obtainSysRole(Long.valueOf(roleId), sysRoleMap);
                        if (!ObjectUtils.isEmpty(sysRoleInfoVO)) {
                            s.getRoleList().add(sysRoleInfoVO);
                        }
                    });
                });
        return new PagerEntity(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    /**
     * 用户列表分页接口
     *
     * @param vo 入参
     * @return 用户列表
     */
    @Deprecated
    public PagerEntity selectPage(SelectUserListRequestVO vo) {
        if (ObjectUtils.isEmpty(vo.getPageIndex())) {
            throw new BaseException(BaseErrorCode.PAGE_INDEX_IS_NULL.getCode(), BaseErrorCode.PAGE_INDEX_IS_NULL.getMessage());
        }
        if (ObjectUtils.isEmpty(vo.getPageSize())) {
            throw new BaseException(BaseErrorCode.PAGE_SIZE_IS_NULL.getCode(), BaseErrorCode.PAGE_SIZE_IS_NULL.getMessage());
        }
        Integer total = sysUserMapper.countByPage(vo);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectUserDetailResponseVO> result = sysUserMapper
                .selectPage(vo, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(vo.getSortMap()));
        // 对角色去重
        Set<Long> roleIdSet = new HashSet<>();
        result.stream().filter(s -> !StringUtils.isEmpty(s.getRoles()))
                .forEach(s -> {
                    List<String> roleIds = Arrays.asList(s.getRoles().trim().split(","));
                    for (String roleId : roleIds) {
                        roleIdSet.add(Long.valueOf(roleId));
                    }
                });
        List<Long> roleIdList = new ArrayList<>(roleIdSet);
        // 角色集合
        Map<Long, SysRole> sysRoleMap = sysRoleDomain.qryRoleMapByIdList(roleIdList);
        result.stream()
                .filter(s -> !StringUtils.isEmpty(s.getRoles()))
                .forEach(s -> {
                    List<String> roleIds = Arrays.asList(s.getRoles().trim().split(","));
                    roleIds.forEach(roleId -> {
                        SysRoleInfoVO sysRoleInfoVO = this.obtainSysRole(Long.valueOf(roleId), sysRoleMap);
                        if (!ObjectUtils.isEmpty(sysRoleInfoVO)) {
                            s.getRoleList().add(sysRoleInfoVO);
                        }
                    });
                });
        return new PagerEntity(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    public PagerEntity selectPageEntity(SelectUserListRequestVO vo) {
        if (ObjectUtils.isEmpty(vo.getPageIndex())) {
            throw new BaseException(BaseErrorCode.PAGE_INDEX_IS_NULL.getCode(), BaseErrorCode.PAGE_INDEX_IS_NULL.getMessage());
        }
        if (ObjectUtils.isEmpty(vo.getPageSize())) {
            throw new BaseException(BaseErrorCode.PAGE_SIZE_IS_NULL.getCode(), BaseErrorCode.PAGE_SIZE_IS_NULL.getMessage());
        }
        Integer total = sysUserMapper.countEntityByPage(vo);
        Pager pager = Pager.newInstance(total.longValue(), vo.getPageIndex(), vo.getPageSize());
        List<SelectUserDetailResponseVO> result = sysUserMapper
                .selectPageEntity(vo, pager.getStart(), pager.getEnd(), CoreTools.getSortStr(vo.getSortMap()));
        return new PagerEntity(total, pager.getTotalPages(), pager.getPageSize(), pager.getPageIndex(), result);
    }

    /**
     * 获取角色信息
     *
     * @param roleId     角色标识
     * @param sysRoleMap 角色集合
     * @return 角色信息
     */
    private SysRoleInfoVO obtainSysRole(Long roleId, Map<Long, SysRole> sysRoleMap) {
        SysRole sysRole = MapUtil.get(sysRoleMap, roleId, SysRole.class, null);
        if (!ObjectUtils.isEmpty(sysRole)) {
            SysRoleInfoVO sysRoleInfoVO = new SysRoleInfoVO();
            sysRoleInfoVO.setRoleId(roleId);
            sysRoleInfoVO.setRoleName(sysRole.getRoleName());
            return sysRoleInfoVO;
        }
        return null;
    }

    /**
     * 通过用户列表查询用户信息
     *
     * @param userIdList 用户列表
     * @return 员工集合
     */
    public Map<Long, SysUser> qryUserMapByIdList(List<Long> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return Collections.emptyMap();
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserIdList(userIdList);
        List<SysUser> sysUserList = sysUserMapper.listByParaDefaultAll(sysUser, null);
        return sysUserList.stream().collect(Collectors.toMap(BaseEntity::getId, k -> k, (v1, v2) -> v2));
    }

    /**
     * 通过员工编码列表查询用户信息
     *
     * @param employeeCodeList 员工工号列表
     * @return 用户集合
     */
    public Map<String, SysUser> qryUserMapByEmployeeCodes(List<String> employeeCodeList) {
        if (CollectionUtils.isEmpty(employeeCodeList)) {
            return Collections.emptyMap();
        }
        SysUser sysUser = new SysUser();
        sysUser.setEmployeeCodeList(employeeCodeList);
        List<SysUser> sysUserList = sysUserMapper.listByParaDefaultAll(sysUser, null);
        return sysUserList.stream().filter(item -> org.apache.commons.lang3.StringUtils.isNotEmpty(item.getEmployeeCode())).collect(Collectors.toMap(SysUser::getEmployeeCode, k -> k, (v1, v2) -> v2));
    }

    /**
     * 通过员工编码列表查询用户id信息
     *
     * @param employeeCodeList 员工工号列表
     * @return 用户集合
     */
    public Map<Long, SysUser> qryUserMapByCodeList(List<String> employeeCodeList) {
        if (CollectionUtils.isEmpty(employeeCodeList)) {
            return Collections.emptyMap();
        }
        SysUser sysUser = new SysUser();
        sysUser.setEmployeeCodeList(employeeCodeList);
        List<SysUser> sysUserList = sysUserMapper.listByParaDefaultAll(sysUser, null);
        return sysUserList.stream().collect(Collectors.toMap(BaseEntity::getId, k -> k, (v1, v2) -> v2));
    }

    public SysUser getByUserAccount(String userAccount) {
        if (userAccount == null || userAccount.isEmpty()) {
            throw new RuntimeException("userAccount不能为空");
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(userAccount);
        List<SysUser> list = sysUserMapper.listByPara(sysUser, null);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public SysUser getByUserAccountDefaultAll(String userAccount,String isDeleted) {
        if (userAccount == null || userAccount.isEmpty()) {
            throw new RuntimeException("userAccount不能为空");
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(userAccount);
        sysUser.setIsDeleted(isDeleted);
        List<SysUser> list = sysUserMapper.listByParaDefaultAll(sysUser, null);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public SysUser getByPhone(String mobile) {
        return sysUserMapper.getByPhone(mobile);
    }

    public List<String> selectRoleListByUser(SelectRoleListByUserRequestVO vo){

        List<String> roleList=sysUserMapper.selectRoleListByUser(vo);
        return roleList;
    }

    public SysUser getOneByEmployeeCode(String employeeCode){
        return sysUserMapper.getOneByEmployeeCode(employeeCode);
    }

    public SysUser getOneByEmployeeCodeDefaultAll(String employeeCode, String isDeleted) {
        return sysUserMapper.getOneByEmployeeCodeDefaultAll(employeeCode, isDeleted);
    }

    public List<RpcUserInfoVO> qryUserInfoByUserListOrAppCode(SelectUserListInfoReqVo vo, LinkedHashMap<String, Object> sortMap){
        return sysUserMapper.qryUserInfoByUserListOrAppCode(vo, CoreTools.getSortStr(sortMap));
    }

    public List<UserOrgInfoResDTO> getOrgsByUser(GetUserOrgsReqVO vo) {
        return sysUserMapper.selectOrgsByUser(vo);
    }

    public List<SysUser> selectListByCondition(SelectOrgUserEmployeeVO vo){
        return sysUserMapper.selectListByCondition(vo);
    }

    public List<EmployeeInfo> selectUserEmployeeListByCondition(SelectOrgUserEmployeeVO vo){
        return sysUserMapper.selectUserEmployeeListByCondition(vo);
    }

    public Integer countUserEmployeeListByCondition(SelectOrgUserEmployeeVO vo){
        return sysUserMapper.countUserEmployeeListByCondition(vo);
    }

    public List<EmployeeInfo> selectUserEmployeeListByEmployeeCode(SelectUserListRequestVO vo){
        return sysUserMapper.selectUserEmployeeListByEmployeeCode(vo);
    }

    public List<EmployeeInfo> selectUserEmployeeListWithIsDeletedByEmployeeCode(SelectUserListRequestVO vo){
        return sysUserMapper.selectUserEmployeeListWithIsDeletedByEmployeeCode(vo);
    }

    public XxlSsoUser checkLoginUserInfo(CurrentUserReqVO vo) {
        Long userId = vo.getUserId();
        String xxlSsoSessionid = vo.getXxlSsoSessionid();
        // 如果userId或者xxlSsoSessionid为空，则从header中获取
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if(ObjectUtils.isEmpty(userId) && !ObjectUtils.isEmpty(request.getHeader("userId"))){
            userId = Long.valueOf(request.getHeader("userId"));
            vo.setUserId(userId);
        }
        if(ObjectUtils.isEmpty(xxlSsoSessionid)){
            xxlSsoSessionid = request.getHeader("xxlSsoSessionid");
            vo.setXxlSsoSessionid(xxlSsoSessionid);
        }
        if(ObjectUtils.isEmpty(userId) || ObjectUtils.isEmpty(xxlSsoSessionid)){
            log.error("userId或xxlSsoSessionid为空，userId:{},xxlSsoSessionid:{}",userId,xxlSsoSessionid);
            throw new BaseException(SysUserErrorCode.USER_ID_OR_XXL_SSO_SESSIONID_IS_NULL.getCode(),SysUserErrorCode.USER_ID_OR_XXL_SSO_SESSIONID_IS_NULL.getMessage());
        }
        // 校验用户是否登录
        XxlSsoUser xxlSsoUser = SsoTokenLoginHelper.loginCheck(xxlSsoSessionid);
        if(ObjectUtils.isEmpty(xxlSsoUser)){
            throw new BaseException(SysUserErrorCode.USER_IS_NOT_LOGIN.getCode(),SysUserErrorCode.USER_IS_NOT_LOGIN.getMessage());
        }
        // 校验登录用户id和传参useId是否一致
        if(!userId.equals(Long.valueOf(xxlSsoUser.getUserid()))){
            throw new BaseException(-1,"当前登录用户和传参userId不匹配，禁止修改其他用户详情");
        }
        return xxlSsoUser;
    }

    /**
     * 校验密码
     * @param userId
     * @param passwd
     */
    public SysUser checkPasswd(Long userId, String passwd) {
        SysUser sysUser = this.getById(userId);
        if (ObjectUtils.isEmpty(sysUser)
                || YesOrNo.Y.name().equals(sysUser.getIsDeleted())
                || !sysUser.getPasswd().equals(SysUserPassWdSaltEnum.encrypt(passwd))) {
            throw new BaseException(SysUserErrorCode.ACCOUNT_OR_PASSWORD_ERROR.getCode(), SysUserErrorCode.ACCOUNT_OR_PASSWORD_ERROR.getMessage());
        }
        return sysUser;
    }

    public Integer deleteById(Long userId){
        return sysUserMapper.deleteById(userId);
    }

    public Integer countByParaExtend(SysUser sysUser) {
        return sysUserMapper.countByParaExtend(sysUser);
    }

    /**
     * 通过用户ID清单查询用户信息
     */
    public List<SysUser> selectUserListByUserIds(List<Long> userIds) {
        return sysUserMapper.selectUserListByUserIds(userIds);
    }

    /**
     * 通过工号ID清单查询用户信息
     */
    public List<SysUser> selectUserListByEmployeeIds(List<Long> employeeIds) {
        return sysUserMapper.selectUserListByEmployeeIds(employeeIds);
    }

    /**
     * 通过组织ID清单查询用户信息
     */
    public List<SysUser> selectUserListByOrgIds(List<Long> orgIds) {
        return sysUserMapper.selectUserListByOrgIds(orgIds);
    }

    /**
     * 通过组织ID清单查询用户信息
     */
    public List<SysUser> selectUserListByPositionIds(List<Long> positionIds) {
        return sysUserMapper.selectUserListByPositionIds(positionIds);
    }

    /**
     * 通过角色ID清单查询用户信息
     */
    public List<SysUser> selectUserListByRoleIds(List<Long> roleIds) {
        return sysUserMapper.selectUserListByRoleIds(roleIds);
    }

    /**
     * 通过人员组ID清单查询用户信息
     */
    public List<SysUser> selectUserListByGroupIds(List<Long> roleIds) {
        return sysUserMapper.selectUserListByGroupIds(roleIds);
    }

    /**
     * 通过人员组ID清单和组织查询用户信息
     */
    public List<SysUser> selectUserListByGroupIdsAndOrg(List<Long> roleIds) {
        return sysUserMapper.selectUserListByGroupIdsAndOrg(roleIds);
    }

    /**
     * 查询用户列表，默认查全部
     */
    public List<SysUser> listByParaDefaultAll(SysUser sysUser, LinkedHashMap<String, Object> sortMap) {
        return sysUserMapper.listByParaDefaultAll(sysUser, CoreTools.getSortStr(sortMap));
    }

    public SysUser getByIdDefaultAll(Long id, String isDeleted) {
        return sysUserMapper.getByIdDefaultAll(id, isDeleted);
    }

    public int updateEmployeeCodeByUserId(SysUser entity) {
        return sysUserMapper.updateEmployeeCodeByUserId(entity);
    }

    public int updateByIdWithIsDeleted(SysUser entity) {
        entity.setGmtModified(LocalDateTime.now());
        return sysUserMapper.updateByIdWithIsDeleted(entity);
    }

    public int updateByIdWithEmptyProperties(SysUser entity){
        return sysUserMapper.updateByIdWithEmptyProperties(entity);
    }

    public SysUser getByIdWithIsDeleted(Long id) {
        return sysUserMapper.getByIdWithIsDeleted(id);
    }

    public List checkEmpIsNotActive(List<String> ecodes) {
        return sysUserMapper.checkEmpIsNotActive(ecodes);
    }

    public Integer getRegisteredUserCount() {
        return sysUserMapper.getRegisteredUserCount();
    }

}
